package com.example.onlinemonitoring.comCenter;

import com.example.onlinemonitoring.Util.CRC16;
import com.example.onlinemonitoring.Util.CommPortManager;
import com.example.onlinemonitoring.Util.HexUtil;
import com.example.onlinemonitoring.Util.IEEE754Utils;
import com.example.onlinemonitoring.model.Jddlsensor;
import com.example.onlinemonitoring.model.Jddlhistory;
import com.example.onlinemonitoring.model.Appdevice;
import com.example.onlinemonitoring.model.Dlhlsensor;
import com.example.onlinemonitoring.serviceImpl.JddlsensorServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.context.annotation.Scope;
import java.text.ParseException;
import java.util.Date;

/*这里beanName需要和数据库Appdevice中的simple对应并加上Com,不对应请自行修改
    例:simple:dlhl
    @Service("dlhlCom")
*/
@Service("jddlCom")
@Scope("prototype")
public class JddlCom extends CommPortManager {
        @Autowired
        private JddlsensorServiceImpl jddlsensorServiceImpl;

        @Override
        public void receiveData(String str) {
            try {
                str = str.toUpperCase();
                setText(str);
                //条件判断自己写
                String addrstr = str.substring(0, 2);
                Integer addrint = parseHex4(addrstr);
        
                reSend[addrindex] = 0;
                addrindex++;
                if (str.length()<12)
                return;
                Integer startIndex = 6;//数据起始位置

                float lastacurrnet = IEEE754Utils.strbytesToSingle(str.substring(startIndex, startIndex += 8)).floatValue();
                float lastbcurrnet = IEEE754Utils.strbytesToSingle(str.substring(startIndex, startIndex += 8)).floatValue();
                float lastccurrnet = IEEE754Utils.strbytesToSingle(str.substring(startIndex, startIndex += 8)).floatValue();
                float lastdcurrnet = IEEE754Utils.strbytesToSingle(str.substring(startIndex, startIndex += 8)).floatValue();
                float lasta1currnet = IEEE754Utils.strbytesToSingle(str.substring(startIndex, startIndex += 8)).floatValue();
                float lastb1currnet = IEEE754Utils.strbytesToSingle(str.substring(startIndex, startIndex += 8)).floatValue();
                float lastc1currnet = IEEE754Utils.strbytesToSingle(str.substring(startIndex, startIndex += 8)).floatValue();
                float lastd1currnet = IEEE754Utils.strbytesToSingle(str.substring(startIndex, startIndex += 8)).floatValue();

                setText("A相环流：" + lastacurrnet + "A" + " B相环流：" + lastbcurrnet + "A" + " C相环流：" + lastccurrnet+ "A" + " 零相环流：" + lastdcurrnet + "A");
                setText("A1相环流：" + lasta1currnet + "A" + " B1相环流：" + lastb1currnet + "A" + " C1相环流：" + lastc1currnet+ "A" + " 零1相环流：" + lastd1currnet + "A");

                Jddlsensor jddlsensor =  new Jddlsensor();
                jddlsensor.setStationid(ad.getStationid());
                jddlsensor.setDevicegroup(ad.getDevicegroup());
                jddlsensor.setDeviceaddr(addrint);
               //查询对象
                Jddlsensor record = jddlsensorServiceImpl.getModel(jddlsensor);
                if (record == null) {
                   setText("当前数据库无监测点：设备地址" + addrint);
                }
                //获取电流系数
                // float agreatevalue = record.getAcurrentcoefficientgreatevalue() == null ? 1f : record.getAcurrentcoefficientgreatevalue();
                // float bgreatevalue = record.getBcurrentcoefficientgreatevalue() == null ? 1f : record.getBcurrentcoefficientgreatevalue();
                // float cgreatevalue = record.getCcurrentcoefficientgreatevalue() == null ? 1f : record.getCcurrentcoefficientgreatevalue();
                // float dgreatevalue = record.getDcurrentcoefficientgreatevalue() == null ? 1f : record.getDcurrentcoefficientgreatevalue();
                // float alessvalue = record.getAcurrentcoefficientlessvalue() == null ? 1f : record.getAcurrentcoefficientlessvalue();
                // float blessvalue = record.getBcurrentcoefficientlessvalue() == null ? 1f : record.getBcurrentcoefficientlessvalue();
                // float clessvalue = record.getCcurrentcoefficientlessvalue() == null ? 1f : record.getCcurrentcoefficientlessvalue();
                // float dlessvalue = record.getDcurrentcoefficientlessvalue() == null ? 1f : record.getDcurrentcoefficientlessvalue();
                               //设置电流相关
                jddlsensor.setLastacurrent(lastacurrnet);
                jddlsensor.setLastbcurrent(lastbcurrnet);
                jddlsensor.setLastccurrent(lastccurrnet);
                jddlsensor.setLastdcurrent(lastdcurrnet);

                jddlsensor.setLasta1current(lasta1currnet);
                jddlsensor.setLastb1current(lastb1currnet);
                jddlsensor.setLastc1current(lastc1currnet);
                jddlsensor.setLastd1current(lastd1currnet);
            //    jddlsensor.setLastacurrent(getCurrent(lastacurrnet, agreatevalue, alessvalue));
            //    jddlsensor.setLastbcurrent(getCurrent(lastbcurrnet, bgreatevalue, blessvalue));
            //    jddlsensor.setLastccurrent(getCurrent(lastccurrnet, cgreatevalue, clessvalue));
            //    jddlsensor.setLastdcurrent(getDcurrent(lastdcurrnet, dgreatevalue, dlessvalue));
               //jddlsensor.setLastacurrentratio(lastacurrnet);
               //jddlsensor.setLastbcurrentratio(lastbcurrnet);
              // jddlsensor.setLastccurrentratio(lastccurrnet);
               //jddlsensor.setLastdcurrentratio(lastdcurrnet);

                AddAndUpdate(record,jddlsensor);

            } catch (Exception ex) {
                ex.printStackTrace();
                setText("从设备返回的数据有误！请检查串口！");
            }
        }

        @Transactional
        private void AddAndUpdate(Jddlsensor record,Jddlsensor Jddl ){
            int alarmLevel = 0;// 报警等级
            String alarmMessage = "";// 报警消息
            //报警逻辑
            //这里写报警逻辑
            if (record.getCurrentalarmvlaue() == null ||
            record.getCurrentalarmrelievevlaue() == null ||
            record.getCurrentwarnvlaue() == null ||
            record.getCurrentwarnrelievevlaue() == null ||
            // record.getCurrentpercentagealarmvlaue() == null ||
            // record.getCurrentpercentagealarmrelievevlaue() == null ||
            // record.getCurrentpercentagewarnvlaue() == null ||
            // record.getCurrentpercentagewarnrelievevlaue() == null ||
            record.getCoefficientalarmvlaue() == null ||
            record.getCoefficientalarmrelievevlaue() == null ||
            record.getCoefficientwarnvlaue() == null ||
            record.getCoefficientwarnrelievevlaue() == null
            ) {
                setText("设备地址" + record.getDeviceaddr() + " 未设置报警值！");
                return;
            }
            //电流报警值
        float currentalarmvlaue = record.getCurrentalarmvlaue();
        //电流报警解除值
        float currentalarmrelievevlaue = record.getCurrentalarmrelievevlaue();
        //电流预警值
        float currentwarnvlaue = record.getCurrentwarnvlaue();
        // 电流预警解除值
        float currentwarnrelievevlaue = record.getCurrentwarnrelievevlaue();
        // // 电流比报警值
        // float currentpercentagealarmvlaue = record.getCurrentpercentagealarmvlaue();
        // // 电流比报警解除值
        // float currentpercentagealarmrelievevlaue = record.getCurrentpercentagealarmrelievevlaue();
        // // 电流比预警值
        // float currentpercentagewarnvlaue = record.getCurrentpercentagewarnvlaue();
        // // 电流比预警解除值
        // float currentpercentagewarnrelievevlaue = record.getCurrentpercentagewarnrelievevlaue();
        // 不平衡系数报警值
        float coefficientalarmvlaue = record.getCoefficientalarmvlaue();
        // 不平衡系数报警解除值
        float coefficientalarmrelievevlaue = record.getCoefficientalarmrelievevlaue();
        // 不平衡系数预警值
        float coefficientwarnvlaue = record.getCoefficientwarnvlaue();
        // 不平衡系数预警解除值
        float coefficientwarnrelievevlaue = record.getCoefficientwarnrelievevlaue();

        //报警逻辑
        float lastacurrent = Jddl.getLastacurrent();
        float lastbcurrent = Jddl.getLastbcurrent();
        float lastccurrent = Jddl.getLastccurrent();
        float lastdcurrent = Jddl.getLastdcurrent();
        //报警逻辑
         float lasta1current = Jddl.getLasta1current();
         float lastb1current = Jddl.getLastb1current();
         float lastc1current = Jddl.getLastc1current();
         float lastd1current = Jddl.getLastd1current();
        //获取最大电流值
        float maxcurrentvalue = Math.max(lastacurrent, lastbcurrent);
        maxcurrentvalue = Math.max(maxcurrentvalue, lastccurrent);
        //获取最小电流值
        float mincurrentvalue = Math.min(lastacurrent, lastbcurrent);
        mincurrentvalue = Math.min(mincurrentvalue, lastccurrent);
        //不平衡系数
        float currnetcoefficient;
        if(maxcurrentvalue==0||mincurrentvalue==0){
            currnetcoefficient = 0;
        }
        else{
            currnetcoefficient = Float.isNaN(maxcurrentvalue / mincurrentvalue) ? 0f : (maxcurrentvalue / mincurrentvalue);
        }
        if(currnetcoefficient>=3)
        {
            if(maxcurrentvalue<=15)
            {
                currnetcoefficient = 2.f;
            }
        }

                //获取最大电流值
        float max1currentvalue = Math.max(lasta1current, lastb1current);
        max1currentvalue = Math.max(max1currentvalue, lastc1current);
        //获取最小电流值
        float min1currentvalue = Math.min(lasta1current, lastb1current);
        min1currentvalue = Math.min(min1currentvalue, lastc1current);
        //不平衡系数
        float currnet1coefficient;
        if(max1currentvalue==0||min1currentvalue==0){
            currnet1coefficient = 0;
        }
        else{
            currnet1coefficient = Float.isNaN(max1currentvalue / min1currentvalue) ? 0f : (max1currentvalue / min1currentvalue);
        }
        if(currnet1coefficient>=3)
        {
            if(max1currentvalue<=15)
            {
                currnet1coefficient = 2.f;
            }
        }
        //电流比
        //float acurrentpercentage;
        //float bcurrentpercentage;
        //float ccurrentpercentage;
        //如果母线电流小于5a则不计算
        // if(lastdcurrent<=5f){
        //     //电流比置0 默认正常
        //     acurrentpercentage = 0f;
        //     bcurrentpercentage = 0f;
        //     ccurrentpercentage = 0f;
        // }else{
        //     if(lastacurrent==0f){
        //         acurrentpercentage=0f;
        //     }else{
        //         acurrentpercentage = lastacurrent / lastdcurrent * 100;
        //     }
        //     if(lastbcurrent==0f){
        //         bcurrentpercentage=0f;
        //     }else{
        //         bcurrentpercentage = lastbcurrent / lastdcurrent * 100;
        //     }
        //     if(lastccurrent==0f){
        //         ccurrentpercentage=0f;
        //     }else{
        //         ccurrentpercentage = lastccurrent / lastdcurrent * 100;
        //     }
        // }
        //定义电流报警状态值
        int acurrentstatus = GetAlarmStatus(lastacurrent, currentalarmvlaue, currentalarmrelievevlaue, currentwarnvlaue, currentwarnrelievevlaue, record.getLastaalarmstatus(), true, "A相环流", record.getDevicegroup(), record.getDeviceaddr(), record.getPointname());
        int bcurrentstatus = GetAlarmStatus(lastbcurrent, currentalarmvlaue, currentalarmrelievevlaue, currentwarnvlaue, currentwarnrelievevlaue, record.getLastbalarmstatus(), true, "B相环流", record.getDevicegroup(), record.getDeviceaddr(), record.getPointname());
        int ccurrentstatus = GetAlarmStatus(lastccurrent, currentalarmvlaue, currentalarmrelievevlaue, currentwarnvlaue, currentwarnrelievevlaue, record.getLastcalarmstatus(), true, "C相环流", record.getDevicegroup(), record.getDeviceaddr(), record.getPointname());
        int a1currentstatus = GetAlarmStatus(lasta1current, currentalarmvlaue, currentalarmrelievevlaue, currentwarnvlaue, currentwarnrelievevlaue, record.getLasta1alarmstatus(), true, "A1相环流", record.getDevicegroup(), record.getDeviceaddr(), record.getPointname());
        int b1currentstatus = GetAlarmStatus(lastb1current, currentalarmvlaue, currentalarmrelievevlaue, currentwarnvlaue, currentwarnrelievevlaue, record.getLastb1alarmstatus(), true, "B1相环流", record.getDevicegroup(), record.getDeviceaddr(), record.getPointname());
        int c1currentstatus = GetAlarmStatus(lastc1current, currentalarmvlaue, currentalarmrelievevlaue, currentwarnvlaue, currentwarnrelievevlaue, record.getLastc1alarmstatus(), true, "C1相环流", record.getDevicegroup(), record.getDeviceaddr(), record.getPointname());     
        //定义电流比报警状态值
        //int acurrentpercentagestatus = GetAlarmStatus(acurrentpercentage, currentpercentagealarmvlaue, currentpercentagealarmrelievevlaue, currentpercentagewarnvlaue, currentpercentagewarnrelievevlaue, record.getLastaralarmstatus(), true, "A相电流比", record.getDevicegroup(), record.getDeviceaddr(), record.getPointname());
        //int bcurrentpercentagestatus = GetAlarmStatus(bcurrentpercentage, currentpercentagealarmvlaue, currentpercentagealarmrelievevlaue, currentpercentagewarnvlaue, currentpercentagewarnrelievevlaue, record.getLastbralarmstatus(), true, "B相电流比", record.getDevicegroup(), record.getDeviceaddr(), record.getPointname());
        //int ccurrentpercentagestatus = GetAlarmStatus(ccurrentpercentage, currentpercentagealarmvlaue, currentpercentagealarmrelievevlaue, currentpercentagewarnvlaue, currentpercentagewarnrelievevlaue, record.getLastcralarmstatus(), true, "C相电流比", record.getDevicegroup(), record.getDeviceaddr(), record.getPointname());
        //定义三相不平衡系数报警值
        int currentcoefficientstatus = GetAlarmStatus(currnetcoefficient, coefficientalarmvlaue, coefficientalarmrelievevlaue, coefficientwarnvlaue, coefficientwarnrelievevlaue, record.getLastabcalarmstatus(), true, "三相不平衡系数", record.getDevicegroup(), record.getDeviceaddr(), record.getPointname());
        int current1coefficientstatus = GetAlarmStatus(currnet1coefficient, coefficientalarmvlaue, coefficientalarmrelievevlaue, coefficientwarnvlaue, coefficientwarnrelievevlaue, record.getLastabc1alarmstatus(), true, "三相不平衡系数1", record.getDevicegroup(), record.getDeviceaddr(), record.getPointname());
        //设置报警状态
        Jddl.setLastaalarmstatus(acurrentstatus);
        Jddl.setLastbalarmstatus(bcurrentstatus);
        Jddl.setLastcalarmstatus(ccurrentstatus);
        Jddl.setLasta1alarmstatus(a1currentstatus);
        Jddl.setLastb1alarmstatus(b1currentstatus);
        Jddl.setLastc1alarmstatus(c1currentstatus);
       // Jddl.setLastaralarmstatus(acurrentpercentagestatus);
       // Jddl.setLastbralarmstatus(bcurrentpercentagestatus);
       // Jddl.setLastcralarmstatus(ccurrentpercentagestatus);
        Jddl.setLastabcalarmstatus(currentcoefficientstatus);
        Jddl.setLastabc1alarmstatus(current1coefficientstatus);
        //设置电流系数
        Jddl.setLastcoefficient(Float.isNaN(currnetcoefficient) ? 0f : currnetcoefficient);
        Jddl.setLastcoefficient1(Float.isNaN(currnet1coefficient) ? 0f : currnet1coefficient);
        Jddl.setLastalarmmessage(GetAlarmMessage(acurrentstatus, "A相环流") +
                GetAlarmMessage(bcurrentstatus, "B相环流") +
                GetAlarmMessage(ccurrentstatus, "C相环流") +
                GetAlarmMessage(a1currentstatus, "A1相环流") +
                GetAlarmMessage(b1currentstatus, "B1相环流") +
                GetAlarmMessage(c1currentstatus, "C1相环流") +
                //GetAlarmMessage(acurrentpercentagestatus, "A相A/R") +
               // GetAlarmMessage(bcurrentpercentagestatus, "B相A/R") +
               // GetAlarmMessage(ccurrentpercentagestatus, "C相A/R") +
                GetAlarmMessage(currentcoefficientstatus, "三相不平衡系数")+
                GetAlarmMessage(current1coefficientstatus, "三相不平衡系数1")
        );

        int[] status_arr = {Jddl.getLastaalarmstatus(), Jddl.getLastbalarmstatus(), Jddl.getLastcalarmstatus(), 
            //Jddl.getLastaralarmstatus(), Jddl.getLastbralarmstatus(), Jddl.getLastcralarmstatus()
            Jddl.getLastabcalarmstatus(),
           Jddl.getLasta1alarmstatus(), Jddl.getLastb1alarmstatus(), Jddl.getLastc1alarmstatus(), 
           // dlhl.getLastar1alarmstatus(), dlhl.getLastbr1alarmstatus(), dlhl.getLastcr1alarmstatus()
           Jddl.getLastabc1alarmstatus()
        };
        //Jddl.setStyle(record.getStyle());
        //设置总报警等级
        Jddl.setLastalarmlevel(MAX(status_arr));
           // Jddl.setLastalarmmessage(alarmMessage);
            Jddl.setLastcommunicationstatus(0);
            Jddl.setLastdatatime(new Date());
            Jddl.setPointname(record.getPointname());
            Jddl.setLasthisdatatime(addHistory(record));
            if ( jddlsensorServiceImpl.Update(Jddl, false) == 0) {
                setText("更新实时数据失败，请检查数据库连接");
            }
        }
        private Date addHistory(Jddlsensor sensor) {
            if (sensor != null) {
                if (sensor.getLasthisdatatime() == null) {
                    add(sensor);
                    return new Date();
                } else {
                    long lasttime = 0;
                    long nowtime = 0;
                    try {
                        lasttime = HexUtil.todate(sensor.getLasthisdatatime()).getTime();
                        nowtime = HexUtil.todate(new Date()).getTime();
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                    int timersp = 60000;
                    if (sensor.getLastalarmlevel() != 0) {
                        timersp = ad.getHisalarmtimersp()*1000;
                    } else {
                        timersp = ad.getHistimersp()*1000;
                    }
                    if (lasttime + timersp < nowtime) {
                        add(sensor);
                        return new Date();
                    }
                }
            }
            return null;
        }

        private void add(Jddlsensor sensor) {
            Jddlhistory his = new Jddlhistory();
            his.setDeviceaddr(sensor.getDeviceaddr());
            his.setDevicegroup(sensor.getDevicegroup());
            his.setAlarmlevel(sensor.getLastalarmlevel());
            his.setAlarmmessage(sensor.getLastalarmmessage());
            his.setDatatime(sensor.getLastdatatime());
            his.setPointname(sensor.getPointname());
            his.setStationid(sensor.getStationid());
            //需要添加自己定义的属性
            his.setAcurrent(sensor.getLastacurrent());
            his.setBcurrent(sensor.getLastbcurrent());
            his.setCcurrent(sensor.getLastccurrent());
            his.setA1current(sensor.getLasta1current());
            his.setB1current(sensor.getLastb1current());
            his.setC1current(sensor.getLastc1current());
            his.setD1current(sensor.getLastd1current());
            his.setCoefficient1(sensor.getLastcoefficient1());
            his.setCoefficient(sensor.getLastcoefficient());
            his.setDcurrent(sensor.getLastdcurrent());
            his.setAalarmstatus(sensor.getLastaalarmstatus());
            his.setBalarmstatus(sensor.getLastbalarmstatus());
            his.setCalarmstatus(sensor.getLastcalarmstatus());
            his.setA1alarmstatus(sensor.getLasta1alarmstatus());
            his.setB1alarmstatus(sensor.getLastb1alarmstatus());
            his.setC1alarmstatus(sensor.getLastc1alarmstatus());
            jddlsensorServiceImpl.Add(his);
        }
    /**
     * 判断电流大小并与系数计算返回校正后的电流
     *
     * @param current
     * @param greateValue
     * @param lessValue
     * @return
     */
    public float getCurrent(float current, float greateValue, float lessValue) {
        float value = current;
        //current = current-0.5f;
        if (current >= 10) {
            value =  current * greateValue;
        } else if (current < 10) {
            value =  current * lessValue;
        }
        return Float.isNaN(value)?0f:value;
    }
    private Float getDcurrent(float current, float greateValue, float lessValue) {
        float value = current;
        if (current >= 180) {
            value =  current * greateValue;
        } else if (current < 180) {
            value =  current * lessValue;
        }
        return Float.isNaN(value)?0f:value;
    }

        @Async("threadPool")
        public void startSendThread(Appdevice Appdevice) throws Exception {
            checkType = "crc16";
            issend.put(Thread.currentThread().getId(), true);
            String cstr = "";
            String cmdtype = "";
            String nametype = "";
            int timersp = (int) Math.round(Appdevice.getTimersp() * 1000);
            while (issend.get(Thread.currentThread().getId()) != null) {
                if (addrindex > Appdevice.getAddrmax() || addrindex < Appdevice.getAddrmin())
                    addrindex = Appdevice.getAddrmin();
                cstr = String.format(Appdevice.getCmd(), String.format("%02X", addrindex));
                cstr = cstr + CRC16.calcCrc16(cstr);
                try {
                    Send(cstr);
                } catch (Exception EX) {
                     setText(EX.toString());
                }
                setText("向" + Appdevice.getName() + "设备发送指令" + cstr);
                reSend[addrindex]++;
                if (reSend[addrindex] > 3) {
                jddlsensorServiceImpl.UpdateStatus(ad, addrindex,1);
                reSend[addrindex] = 0;
                addrindex++;
                }
                Thread.sleep(timersp);
            }
        }

        // @Async("threadPool")
        // public void startReceiveThread(){
        //     isrecv.put(Thread.currentThread().getId(), true);
        //     while (isrecv.get(Thread.currentThread().getId()) != null) {
        //         //这里根据实际协议替换,解析方法recvCrc16;recvSum();
        //         recv();
        //         try {
        //             Thread.sleep(interval);
        //         } catch (InterruptedException e) {
        //             e.printStackTrace();
        //         }
        //     }
        // }
}
